use super::super::method::{Method, MethodType};
use super::super::value::{Value, ValueData};
use std::cell::RefCell;
use std::collections::HashMap;
use std::rc::Rc;

/// 列表类型的实现
pub struct List;

impl List {
    /// 创建列表值
    pub fn create(elements: Vec<Value>) -> Value {
        let mut methods = HashMap::new();

        // 查询方法
        methods.insert(
            "长度".to_string(),
            Method::native(MethodType::List, |args| {
                if let ValueData::List(elements) = &args[0].data {
                    Ok(Value::number(elements.borrow().len() as f64))
                } else {
                    Err("不是列表类型".to_string())
                }
            }),
        );

        methods.insert(
            "空否".to_string(),
            Method::native(MethodType::List, |args| {
                if let ValueData::List(elements) = &args[0].data {
                    Ok(Value::boolean(elements.borrow().is_empty()))
                } else {
                    Err("不是列表类型".to_string())
                }
            }),
        );

        methods.insert(
            "获取".to_string(),
            Method::native(MethodType::List, |args| {
                if let (ValueData::List(elements), ValueData::Number(index)) =
                    (&args[0].data, &args[1].data)
                {
                    let len = elements.borrow().len();
                    let idx = Self::normalize_index(*index as isize, len);
                    if idx < 0 || idx >= len as isize {
                        Err("索引越界".to_string())
                    } else {
                        Ok(elements.borrow()[idx as usize].clone())
                    }
                } else {
                    Err("不是列表类型".to_string())
                }
            }),
        );

        methods.insert(
            "首".to_string(),
            Method::native(MethodType::List, |args| {
                if let ValueData::List(elements) = &args[0].data {
                    let elements = elements.borrow();
                    if elements.is_empty() {
                        Err("列表为空".to_string())
                    } else {
                        Ok(elements[0].clone())
                    }
                } else {
                    Err("不是列表类型".to_string())
                }
            }),
        );

        methods.insert(
            "尾".to_string(),
            Method::native(MethodType::List, |args| {
                if let ValueData::List(elements) = &args[0].data {
                    let elements = elements.borrow();
                    if elements.is_empty() {
                        Err("列表为空".to_string())
                    } else {
                        Ok(elements.last().unwrap().clone())
                    }
                } else {
                    Err("不是列表类型".to_string())
                }
            }),
        );

        methods.insert(
            "包含".to_string(),
            Method::native(MethodType::List, |args| {
                if let (ValueData::List(elements), elem) = (&args[0].data, &args[1]) {
                    let contains = elements.borrow().contains(elem);
                    Ok(Value::boolean(contains))
                } else {
                    Err("不是列表类型".to_string())
                }
            }),
        );

        methods.insert(
            "索引".to_string(),
            Method::native(MethodType::List, |args| {
                if let (ValueData::List(elements), elem) = (&args[0].data, &args[1]) {
                    let elements = elements.borrow();
                    if let Some(index) = elements.iter().position(|x| x == elem) {
                        Ok(Value::number(index as f64))
                    } else {
                        Ok(Value::number(-1.0))
                    }
                } else {
                    Err("不是列表类型".to_string())
                }
            }),
        );

        methods.insert(
            "计数".to_string(),
            Method::native(MethodType::List, |args| {
                if let (ValueData::List(elements), elem) = (&args[0].data, &args[1]) {
                    let count = elements.borrow().iter().filter(|x| *x == elem).count();
                    Ok(Value::number(count as f64))
                } else {
                    Err("不是列表类型".to_string())
                }
            }),
        );

        // 修改方法
        methods.insert(
            "添加".to_string(),
            Method::native(MethodType::List, |args| {
                if let (ValueData::List(elements), elem) = (&args[0].data, &args[1]) {
                    elements.borrow_mut().push(elem.clone());
                    Ok(args[0].clone())
                } else {
                    Err("不是列表类型".to_string())
                }
            }),
        );

        methods.insert(
            "插入".to_string(),
            Method::native(MethodType::List, |args| {
                if let (ValueData::List(elements), ValueData::Number(index), elem) =
                    (&args[0].data, &args[1].data, &args[2])
                {
                    let len = elements.borrow().len();
                    let idx = Self::normalize_index(*index as isize, len);
                    let idx = idx as usize;
                    if idx <= len {
                        elements.borrow_mut().insert(idx, elem.clone());
                        Ok(args[0].clone())
                    } else {
                        Err("索引越界".to_string())
                    }
                } else {
                    Err("不是列表类型".to_string())
                }
            }),
        );

        methods.insert(
            "设置".to_string(),
            Method::native(MethodType::List, |args| {
                if let (ValueData::List(elements), ValueData::Number(index), elem) =
                    (&args[0].data, &args[1].data, &args[2])
                {
                    let len = elements.borrow().len();
                    let idx = Self::normalize_index(*index as isize, len);
                    if idx >= 0 && idx < len as isize {
                        elements.borrow_mut()[idx as usize] = elem.clone();
                        Ok(args[0].clone())
                    } else {
                        Err("索引越界".to_string())
                    }
                } else {
                    Err("不是列表类型".to_string())
                }
            }),
        );

        methods.insert(
            "移除".to_string(),
            Method::native(MethodType::List, |args| {
                if let (ValueData::List(elements), ValueData::Number(index)) =
                    (&args[0].data, &args[1].data)
                {
                    let len = elements.borrow().len();
                    let idx = Self::normalize_index(*index as isize, len);
                    if idx >= 0 && idx < len as isize {
                        let elem = elements.borrow_mut().remove(idx as usize);
                        Ok(elem)
                    } else {
                        Err("索引越界".to_string())
                    }
                } else {
                    Err("不是列表类型".to_string())
                }
            }),
        );

        methods.insert(
            "删除".to_string(),
            Method::native(MethodType::List, |args| {
                if let (ValueData::List(elements), elem) = (&args[0].data, &args[1]) {
                    let mut borrowed = elements.borrow_mut();
                    if let Some(index) = borrowed.iter().position(|x| x == elem) {
                        borrowed.remove(index);
                        Ok(Value::boolean(true))
                    } else {
                        Ok(Value::boolean(false))
                    }
                } else {
                    Err("不是列表类型".to_string())
                }
            }),
        );

        methods.insert(
            "清空".to_string(),
            Method::native(MethodType::List, |args| {
                if let ValueData::List(elements) = &args[0].data {
                    elements.borrow_mut().clear();
                    Ok(args[0].clone())
                } else {
                    Err("不是列表类型".to_string())
                }
            }),
        );

        methods.insert(
            "弹出".to_string(),
            Method::native(MethodType::List, |args| {
                if let ValueData::List(elements) = &args[0].data {
                    let mut borrowed = elements.borrow_mut();
                    if let Some(elem) = borrowed.pop() {
                        Ok(elem)
                    } else {
                        Err("列表为空".to_string())
                    }
                } else {
                    Err("不是列表类型".to_string())
                }
            }),
        );

        // 转换方法
        methods.insert(
            "排序".to_string(),
            Method::native(MethodType::List, |args| {
                if let ValueData::List(elements) = &args[0].data {
                    let mut vec = elements.borrow_mut().clone();
                    vec.sort_by(|a, b| match (&a.data, &b.data) {
                        (ValueData::Number(n1), ValueData::Number(n2)) => {
                            n1.partial_cmp(n2).unwrap_or(std::cmp::Ordering::Equal)
                        }
                        _ => std::cmp::Ordering::Equal,
                    });
                    *elements.borrow_mut() = vec;
                    Ok(args[0].clone())
                } else {
                    Err("不是列表类型".to_string())
                }
            }),
        );

        methods.insert(
            "倒序排序".to_string(),
            Method::native(MethodType::List, |args| {
                if let ValueData::List(elements) = &args[0].data {
                    let mut vec = elements.borrow_mut().clone();
                    vec.sort_by(|a, b| match (&a.data, &b.data) {
                        (ValueData::Number(n1), ValueData::Number(n2)) => {
                            n2.partial_cmp(n1).unwrap_or(std::cmp::Ordering::Equal)
                        }
                        _ => std::cmp::Ordering::Equal,
                    });
                    *elements.borrow_mut() = vec;
                    Ok(args[0].clone())
                } else {
                    Err("不是列表类型".to_string())
                }
            }),
        );

        methods.insert(
            "反转".to_string(),
            Method::native(MethodType::List, |args| {
                if let ValueData::List(elements) = &args[0].data {
                    elements.borrow_mut().reverse();
                    Ok(args[0].clone())
                } else {
                    Err("不是列表类型".to_string())
                }
            }),
        );

        methods.insert(
            "复制".to_string(),
            Method::native(MethodType::List, |args| {
                if let ValueData::List(elements) = &args[0].data {
                    let elements = elements.borrow();
                    let new_elements: Vec<Value> = elements.iter().cloned().collect();
                    Ok(Value::list(new_elements))
                } else {
                    Err("不是列表类型".to_string())
                }
            }),
        );

        methods.insert(
            "深复制".to_string(),
            Method::native(MethodType::List, |args| {
                if let ValueData::List(elements) = &args[0].data {
                    // 简单的深复制实现，实际项目中可能需要更复杂的实现
                    let elements = elements.borrow();
                    let new_elements: Vec<Value> = elements.iter().cloned().collect();
                    Ok(Value::list(new_elements))
                } else {
                    Err("不是列表类型".to_string())
                }
            }),
        );

        methods.insert(
            "切片".to_string(),
            Method::native(MethodType::List, |args| {
                if let (
                    ValueData::List(elements),
                    ValueData::Number(start),
                    ValueData::Number(end),
                ) = (&args[0].data, &args[1].data, &args[2].data)
                {
                    let elements = elements.borrow();
                    let len = elements.len();
                    let start_idx = Self::normalize_index(*start as isize, len);
                    let end_idx = Self::normalize_index(*end as isize, len);

                    if start_idx < 0 {
                        return Err("起始索引越界".to_string());
                    }

                    let start_idx = start_idx as usize;
                    // 结束索引需要加1，因为切片要包含结束索引
                    let end_idx = (end_idx + 1) as usize;

                    if end_idx > len {
                        return Err("结束索引越界".to_string());
                    }

                    if start_idx >= end_idx {
                        return Ok(Value::list(vec![]));
                    }

                    let sliced: Vec<Value> = elements[start_idx..end_idx].iter().cloned().collect();
                    Ok(Value::list(sliced))
                } else {
                    Err("不是列表类型".to_string())
                }
            }),
        );

        methods.insert(
            "连接".to_string(),
            Method::native(MethodType::List, |args| {
                if let (ValueData::List(elements1), ValueData::List(elements2)) =
                    (&args[0].data, &args[1].data)
                {
                    let mut new_elements = elements1.borrow().clone();
                    new_elements.extend(elements2.borrow().iter().cloned());
                    Ok(Value::list(new_elements))
                } else {
                    Err("不是列表类型".to_string())
                }
            }),
        );

        // 高阶方法
        methods.insert(
            "映射".to_string(),
            Method::native(
                MethodType::List,
                |_args| Err("映射方法尚未实现".to_string()),
            ),
        );

        methods.insert(
            "筛选".to_string(),
            Method::native(
                MethodType::List,
                |_args| Err("筛选方法尚未实现".to_string()),
            ),
        );

        methods.insert(
            "归约".to_string(),
            Method::native(
                MethodType::List,
                |_args| Err("归约方法尚未实现".to_string()),
            ),
        );

        methods.insert(
            "遍历".to_string(),
            Method::native(
                MethodType::List,
                |_args| Err("遍历方法尚未实现".to_string()),
            ),
        );

        methods.insert(
            "全部满足".to_string(),
            Method::native(MethodType::List, |_args| {
                Err("全部满足方法尚未实现".to_string())
            }),
        );

        methods.insert(
            "存在满足".to_string(),
            Method::native(MethodType::List, |_args| {
                Err("存在满足方法尚未实现".to_string())
            }),
        );

        // 添加通用方法
        super::super::value::Value::add_common_methods(&mut methods, "集");

        Value {
            type_name: "集".to_string(),
            data: ValueData::List(Rc::new(RefCell::new(elements))),
            methods: Rc::new(RefCell::new(methods)),
        }
    }

    /// 规范化索引，支持负索引
    fn normalize_index(index: isize, len: usize) -> isize {
        if index < 0 {
            (len as isize) + index
        } else {
            index
        }
    }
}
